import PATH_LIST from '@router/path-list'
import PATH_REPALCE from '@router/path-list/PATH_REPALCE'

import {
  IS_FROM_APP, // 是否嵌入 app
  IS_PC_APP, // 是否为 pc 项目
  getCookie,
} from '@utils/utils'
import {
  getRole,
} from '@utils/role'
import {
  setSignIn,
  getSignInByKey,
  setSignOut,
  isLogin,
} from '@utils/storage_base_config'
import {
  PC_URL_PREFIX,
} from '@utils/default_config'

import Toast from '@utils/toast'
// 首页
export const HOME_PATH_NAME = IS_PC_APP ? 'pc/index' : 'index'
// 登陆页
export const LOGIN_PATH_NAME = IS_PC_APP ? 'pc/login' : 'login'
// 1. 无权限时重定向到的页面；2. 访问登录页且已登录时跳转。
// NOTE: 游客不可访问pc。这个限制在 checkAuthorization 中统一拦截，跳转到登录页。
export const NO_AUTHORITY_PATH_NAME = IS_PC_APP ? 'pc/index' : 'profile'
// 404 页面
export const NO_FIND_PATH_NAME = IS_PC_APP ? 'pc/404' : '404'

/**
 * 路由访问前的鉴权以及同步cookie的动作
 */
export function beforeRouteEnter() {
  if (IS_FROM_APP) {
    const token = getCookie('access_token')
    if (!token) {
      console.log('not cookie token', token, 'try again -->')
      return false
    }
    console.log('token', token)
    console.log('access_token', getSignInByKey('access_token'))
    if (getSignInByKey('access_token') != token) {
      setSignIn({
        access_token: token,
        role: '1', // APP 固定分销商登录
      })
      setTimeout(() => {
        window.location.reload()
      }, 100)
    }
    // NOTE: APP 只有分销商端，暂时不必进行权限校验。
    return true
  }

  const pageName = getPageName()

  if (!pageName) {
    debugger
    goPage(NO_FIND_PATH_NAME)
  }

  if (isLogin()) {
    // 访问登录页且已登录时，跳转到默认页
    if (pageName === LOGIN_PATH_NAME) {
      debugger
      goPage(NO_AUTHORITY_PATH_NAME)
      return false
    }
  }

  // 校验访问权限。若不通过，直接跳转页面
  return checkAuthorization(pageName)
}

/**
 * 校验访问权限。若不通过，直接跳转页面
 * @param {String} pageName 需要校验的页面名称。可缺省，默认校验当前页面
 * @param {String} pageParams 页面参数。可缺省，默认从 url 上获取。
 */
function checkAuthorization(pageName, pageParams) {
  const pathObj = pageName ?
    PATH_LIST.find(item => item['name'] === pageName) :
    PATH_LIST.find(item => item['mount_path'] === localStorage.MOUNT_PATH)
  if (!pathObj) {
    console.error('路由名称有误，找不到匹配的路由')
    return true
  }
  if (!pageParams)
    pageParams = getUrlParams()

  const is_login = isLogin(),
    role = getRole() || ''

  // 如果更换角色，判断为退出
  const urlRole = pageParams.role || getUrlParam('role')
  if (urlRole && urlRole !== role && pathObj.name !== LOGIN_PATH_NAME) {
    debugger
    console.error('权限发生变换，跳转登录。')
    setSignOut()
    goPage(LOGIN_PATH_NAME, {
      redirect: createUrl(pathObj.name, pageParams),
      ...pageParams,
      role: urlRole,
    }, true)
    return false
  }

  // 游客不可访问 pc
  if (IS_PC_APP && role === '0' && pathObj.name !== LOGIN_PATH_NAME) {
    debugger
    console.error('[游客]缺少访问权限，跳转登录。')
    setSignOut()
    goPage(LOGIN_PATH_NAME, {
      redirect: createUrl(pathObj.name, pageParams),
      ...pageParams
    }, true)
  }

  let isTest = false
  switch (pathObj.authority) {
    case 'allow-distributor': // 只允许分销商访问
      isTest = is_login && role === '1'
      break
    case 'allow-secret': // 加价转发加密串
      isTest = is_login || !!getUrlParam('secret')
      break
    case false: // 不需要登录
      isTest = true
      break
    default: // 默认只允许登录后访问
      isTest = is_login
  }

  if (!isTest) {
    debugger
    if (is_login) {
      console.error('缺少访问权限，跳转默认。')
      Toast('您无权访问该页面')
      goPage(NO_AUTHORITY_PATH_NAME, {}, true)
    } else {
      console.error('缺少访问权限，跳转登录。')
      setSignOut()
      pageParams || (pageParams = getUrlParams())
      goPage(LOGIN_PATH_NAME, {
        redirect: createUrl(pathObj.name, pageParams),
        ...pageParams
      }, true)
    }
    return false
  }

  return true
}

/**
 * 获取当前页面 pageName
 */
export function getPageName() {
  const MOUNT_PATH = localStorage.MOUNT_PATH
  const thisPathObj = PATH_LIST.find(item => item['mount_path'] === MOUNT_PATH) || {}
  return thisPathObj.name
}

/**
 * 获取url参数
 */
export function getUrlParam(name, str) {
  str = str ? str : location.href
  return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(str) || [, ""])[1].replace(/\+/g, '%20')) || null
}

/**
 * 获取地址栏所有参数
 * @returns {Object} json 格式的所有参数
 */
export function getUrlParams() {
  var urlParams = {},
    match,
    search = /([^&=]+)=?([^&]*)/g,
    query = window.location.search.substring(1),
    pl = /\+/g,
    decodeFn = function(s) {
      return decodeURIComponent(s.replace(pl, " "));
    };
  while (match = search.exec(query)) {
    urlParams[decodeFn(match[1])] = decodeFn(match[2]);
  }
  return urlParams;
};

/**
 * 合并当前页面参数
 * @param {Object} params 页面参数
 */
export function mergePageParams(params) {
  history.replaceState(null, null, createUrl(null, params, true))
}

/**
 * 返回上一页
 * 如果没有上一页的历史，则返回默认页或者首页
 * @param {String} defPageName
 * @param {String} defPageParams
 */
export function goPageBack(defPageName, defPageParams) {
  // TODO: 判断是否站内地址
  if (document.referrer !== '' &&
    !document.referrer.includes(getPagePath(LOGIN_PATH_NAME)) // 不返回登录页
  )
    history.back()
  else
    goPage(defPageName || HOME_PATH_NAME, defPageParams, true)
}

/**
 * 跳转页面
 * @param {String} pageName 页面地址。如果不设置页面地址则返回上一页
 * @param {Object} pageParams 页面参数
 * @param {Boolean} isReplace 是否替换路由。默认不替换
 */
export function goPage(pageName, pageParams, isReplace) {
  if (!checkAuthorization(pageName, pageParams))
    return
  const path = getPagePath(pageName, pageParams)
  if (!path) {
    debugger
    goPage(NO_FIND_PATH_NAME)
    return
  }
  isReplace ? window.location.replace(path) : (window.location.href = path);
}

/**
 * 获取项目页面地址
 * @param {String} pageName 页面名称。
 * @param {String} pageParams 页面参数。
 */
export function getPagePath(pageName, pageParams) {
  var pathObj = PATH_LIST.find(item => item['name'] === pageName)
  if (!pathObj) {
    console.error('路由名称有误，找不到匹配的路由')
    return ''
  }

  const suffix = process.env.NODE_ENV === 'development' ? '.html' : '', // 后缀
    path = pathObj.path + suffix
  return createUrl(path, pageParams)
}

/**
 * 生成一个带参数的 url
 * @param {*} url 默认为当前页面地址
 * @param {*} params url参数
 * @param {*} isMergeParams 是否合并旧参数。默认不合并，替换所有参数
 */
export function createUrl(url, params, isMergeParams) {
  url || (url = window.location.href)
  if (!params || !Object.keys(params).length)
    return url;

  if (isMergeParams) {
    var oldParams = getUrlParams(url);
    params = Object.assign(oldParams, params);
  }
  var str = '';
  for (var key in params) {
    if (params[key] !== null) {
      str += (key + '=' + encodeURIComponent(params[key]) + '&');
    }
  }

  var index = url.lastIndexOf('?');
  if (index >= 0)
    url = url.substring(0, index)

  return url + '?' + str.substring(0, str.lastIndexOf('&'));
}

/**
 * 替换版本链接。m版项目中，把pc地址替换为m。pc项目中，把m地址替换为pc。
 * @param {*} url 要替换的地址。注意，必须是完整的url地址。
 * @param {*} appType 要替换成的版本。可选：'m'|'pc'，默认为当前 APP_TYPE
 */
const ORIGIN = location.origin
// export function replaceAppPath(url) {
//   const regM = new RegExp(`^${ORIGIN}[^${PC_URL_PREFIX}]`),
//     regPC = new RegExp(`^${ORIGIN}${PC_URL_PREFIX}`)
//   if (IS_PC_APP && url.match(regM)) {
//     return url.replace(ORIGIN, ORIGIN + PC_URL_PREFIX)
//   } else if (!IS_PC_APP && url.match(regPC)) {
//     return url.replace(ORIGIN + PC_URL_PREFIX, ORIGIN)
//   }
//   return url
// }
export function replaceAppPath(url, appType) {
  const isReplaceToPC = appType ? appType === 'pc' : !IS_PC_APP
  if (!url ||
    url.indexOf(ORIGIN) != 0 ||
    url.match(new RegExp(isReplaceToPC ? `^${ORIGIN}${PC_URL_PREFIX}` : `^${ORIGIN}[^${PC_URL_PREFIX}]`)))
    return url

  var pathItem = PATH_REPALCE.find(item => {
    const testPath = isReplaceToPC ? item.m_page : item.pc_page
    if (testPath && url.indexOf(testPath) > -1) {
      const params = getUrlParams(url),
        testParams = isReplaceToPC ? item.pc_params : item.m_params
      if (testParams) {
        for (let key in testParams) {
          if (params[key] !== testParams[key])
            return false
        }
      }
      return true
    }
    return false
  })

  if (!pathItem)
    return url

  const pc_page = pathItem.pc_page,
    m_page = pathItem.m_page,
    params = isReplaceToPC ? pathItem.m_params : pathItem.pc_params
  const newUrl = url.replace(isReplaceToPC ? m_page : pc_page, isReplaceToPC ? pc_page : m_page)
  return createUrl(newUrl, params || {}, true)
}